package com.blue.comments.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.blue.comments.mapper.CommentsLikeRepository;
import com.blue.comments.mapper.CommentsRepository;
import com.blue.comments.service.CommentsService;
import com.litblue.common.exception.BizIllegalException;
import com.litblue.common.utils.BeanUtils;
import com.litblue.common.utils.UserContext;
import com.litblue.starter.cache.redis.RedisCache;
import com.litblue.starter.cache.redis.RedisKeys;
import com.litblue.starter.core.AjaxResult;
import com.litblue.starter.pojo.comments.domain.Comment;
import com.litblue.starter.pojo.comments.domain.TotalComments;
import com.litblue.starter.pojo.comments.dto.TotalCommentsDto;
import com.litblue.starter.pojo.comments.vo.CommentVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CommentsServiceImpl implements CommentsService {

    private final CommentsRepository commentsRepository;

    private final RedisCache redisCache;

    private final CommentsLikeRepository commentsLikeRepository;

    @Override
    public AjaxResult addComment(Comment comment) {
        Long user = UserContext.getUser();
        redisCache.deleteKeysByPattern(RedisKeys.LIT_ALL_ARTWORK_VOS_KEY);
        RedisKeys redisKeys = RedisKeys.forArtworkInfo(user.toString(), comment.getArtworkId());
        redisCache.deleteObject(redisKeys.LIT_ARTWORK_INFO_KEY);
        comment.setCreateTime(new Date());
        Comment save = commentsRepository.save(comment);
        if (save==null){
            throw new BizIllegalException("评论失败");
        }
        return new AjaxResult("评论成功","200",null);
    }

    @Override
    public AjaxResult addCommentLike(TotalCommentsDto totalCommentsDto) {
        Long user = UserContext.getUser();
        redisCache.deleteKeysByPattern(RedisKeys.LIT_ALL_ARTWORK_VOS_KEY);
        RedisKeys redisKeys = RedisKeys.forArtworkInfo(user.toString(), totalCommentsDto.getArtworkId());
        redisCache.deleteObject(redisKeys.LIT_ARTWORK_INFO_KEY);
        Optional<TotalComments> totalComments = commentsLikeRepository.queryByCommentIdAndUserId(totalCommentsDto.getCommentId(), totalCommentsDto.getUserId());
        if (totalComments.isPresent()) {
            commentsLikeRepository.delete(totalComments.get());
            return new AjaxResult("取消点赞", "200",null);
        }else {
            TotalCommentsDto save = commentsLikeRepository.save(totalCommentsDto);
            if (save==null){
                return new AjaxResult("点赞失败", "500",null);
            }
        }
        return new AjaxResult("点赞成功", "200",null);
    }

    @Override
    public List<CommentVo> getComments(String artworkId) {
        List<Comment> comments = commentsRepository.findByArtworkId(artworkId);
        Long user = UserContext.getUser();
        if (CollectionUtil.isEmpty(comments)){
            return Collections.emptyList();
        }
        List<CommentVo> commentVos = BeanUtils.copyList(comments, CommentVo.class);
//        获取根评论
        List<CommentVo> rootComments = commentVos.stream().filter(comment -> comment.getParentId().equals("0"))
                .collect(Collectors.toList());
        for (CommentVo rootComment : rootComments) {
            rootComment.setIsLike(isLike(user,rootComment.getId()));
            rootComment.setLikeNums(getCommentLikeNum(rootComment.getId()));
            rootComment.setPublishTime(calculateRelativeTime(rootComment.getCreateTime()));
            List<CommentVo> childComments = getChild(rootComment.getId(), commentVos, user);
            rootComment.setChildRenComment(childComments);
        }

        return commentVos;
    }

    /**
     * 获取节点下的子评论
     */
    List<CommentVo> getChild(String parentId,List<CommentVo> allComments,Long userId){
        ArrayList<CommentVo> commentVos = new ArrayList<>();
        Queue<CommentVo> queue=new LinkedList<>();
        for (CommentVo comment : allComments) {
            if (comment.getParentId().equals(parentId)){
                queue.add(comment);
            }
        }
        while (!queue.isEmpty()){
            CommentVo poll = queue.poll();
            poll.setIsLike(isLike(userId,poll.getId()));
            poll.setLikeNums(getCommentLikeNum(poll.getId()));
            poll.setPublishTime(calculateRelativeTime(poll.getCreateTime()));
            commentVos.add(poll);
//            多级评论
            for (CommentVo comment : allComments) {
                if (comment.getParentId().equals(poll.getId())){
                    queue.add(comment);
                }
            }
        }
        return  commentVos;
    }

    /***
     *
     *获取评论数量
     */
    Integer getCommentNum(String artworkId){
        Integer count = commentsRepository.countByArtworkId(artworkId);
        return count==null?0:count;
    }
    /**
     * 获取评论点赞数量
     */
    Integer getCommentLikeNum(String commentId){
        Integer count = commentsLikeRepository.countByCommentId(commentId);
        return count==null?0:count;
    }
    /**
     * 获取登陆人是否点赞
     */
    Boolean isLike(Long userId,String commentId){
        Optional<TotalComments> totalComments = commentsLikeRepository.queryByCommentIdAndUserId(commentId, userId.toString());
        if (totalComments.isPresent()) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;

    }
    /**
     * 设置评论日期
     * @param createTime
     * @return
     */

    private String calculateRelativeTime(Date createTime) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime commentTime = LocalDateTime.ofInstant(createTime.toInstant(), ZoneId.systemDefault());
        Duration duration = Duration.between(commentTime, now);

        long seconds = duration.getSeconds();
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;

        if (seconds < 60) {
            return seconds + "秒前";
        } else if (minutes < 60) {
            return minutes + "分钟前";
        } else if (hours < 24) {
            return hours + "小时前";
        } else {
            return days + "天前";
        }
    }

}
